package com.kede.app.service.impl;

import com.kede.app.domain.LeescoreAddress;
import com.kede.app.domain.LeescoreOrder;
import com.kede.app.domain.LeescoreOrderGoods;
import com.kede.app.domain.Users;
import com.kede.app.repository.LeescoreAddressRepository;
import com.kede.app.repository.LeescoreOrderGoodsRepository;
import com.kede.app.repository.UsersRepository;
import com.kede.app.service.dto.OrderAddrDto;
import com.kede.utils.ValidationUtil;
import com.kede.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.kede.app.repository.LeescoreOrderRepository;
import com.kede.app.service.LeescoreOrderService;
import com.kede.app.service.dto.LeescoreOrderDto;
import com.kede.app.service.dto.LeescoreOrderQueryCriteria;
import com.kede.app.service.mapstruct.LeescoreOrderMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.kede.utils.PageUtil;
import com.kede.utils.QueryHelp;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @description 服务实现
* @author Pr.li
* @date 2023-05-12
**/
@Service
@RequiredArgsConstructor
public class LeescoreOrderServiceImpl implements LeescoreOrderService {

    private final LeescoreOrderRepository leescoreOrderRepository;
    private final LeescoreOrderMapper leescoreOrderMapper;
    private final UsersRepository usersRepository;
    private final LeescoreOrderGoodsRepository leescoreOrderGoodsRepository;
    private final LeescoreAddressRepository leescoreAddressRepository;

    @Override
    public Map<String,Object> queryAll(LeescoreOrderQueryCriteria criteria, Pageable pageable){
        Page<LeescoreOrder> page = leescoreOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        page.get().forEach(leescoreOrder -> {
            Optional<Users> byId = usersRepository.findById(leescoreOrder.getUid());
            if (byId.isPresent()){
                leescoreOrder.setUsername(byId.get().getUsersName());
                leescoreOrder.setUserphone(byId.get().getUsersPhone());
            }
            Optional<LeescoreAddress> addr = leescoreAddressRepository.findById(leescoreOrder.getAddressId());
            if (addr.isPresent()){
                OrderAddrDto orderAddrDto = new OrderAddrDto();
                StringBuilder builder = new StringBuilder();
                builder.append(addr.get().getRegion());
                builder.append(addr.get().getCity());
                builder.append(addr.get().getXian());
                builder.append(addr.get().getAddress());
                orderAddrDto.setAddress(builder.toString());
                orderAddrDto.setName(addr.get().getFirstname());
                orderAddrDto.setPhone(addr.get().getMobile());
                leescoreOrder.setOrderAddrDto(orderAddrDto);
            }
            List<LeescoreOrderGoods> allByOrderId = leescoreOrderGoodsRepository.findAllByOrderId(leescoreOrder.getId());
            leescoreOrder.setLeescoreOrderGood(allByOrderId);
        });
        return PageUtil.toPage(page.map(leescoreOrderMapper::toDto));
    }

    @Override
    public List<LeescoreOrderDto> queryAll(LeescoreOrderQueryCriteria criteria){
        return leescoreOrderMapper.toDto(leescoreOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public LeescoreOrderDto findById(Integer id) {
        LeescoreOrder leescoreOrder = leescoreOrderRepository.findById(id).orElseGet(LeescoreOrder::new);
        ValidationUtil.isNull(leescoreOrder.getId(),"LeescoreOrder","id",id);
        return leescoreOrderMapper.toDto(leescoreOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LeescoreOrderDto create(LeescoreOrder resources) {
        return leescoreOrderMapper.toDto(leescoreOrderRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(LeescoreOrder resources) {
        LeescoreOrder leescoreOrder = leescoreOrderRepository.findById(resources.getId()).orElseGet(LeescoreOrder::new);
        ValidationUtil.isNull( leescoreOrder.getId(),"LeescoreOrder","id",resources.getId());
        leescoreOrder.copy(resources);
        leescoreOrderRepository.save(leescoreOrder);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            leescoreOrderRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<LeescoreOrderDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (LeescoreOrderDto leescoreOrder : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("用户ID", leescoreOrder.getUid());
            map.put("收货地址", leescoreOrder.getAddressId());
            map.put("订单号", leescoreOrder.getOrderId());
            map.put("回执单号", leescoreOrder.getTradeId());
            map.put("创建时间", leescoreOrder.getCreatetime());
            map.put("付款状态:0=未付款,1=已付款,2=已退款", leescoreOrder.getPay());
            map.put("订单状态:-3=异常订单,-2=驳回, -1=取消订单,0=未支付,1=已支付,2=已发货,3=已签收,4=退货中,5=已退款", leescoreOrder.getStatus());
            map.put("付款时间", leescoreOrder.getPaytime());
            map.put("支付方式:score=积分支付,money=余额支付", leescoreOrder.getPaytype());
            map.put("1", leescoreOrder.getIsdel());
            map.put("备注", leescoreOrder.getOther());
            map.put("虚拟券序列号", leescoreOrder.getVirtualSn());
            map.put("虚拟券名称", leescoreOrder.getVirtualName());
            map.put("发货时间", leescoreOrder.getVirtualGoTime());
            map.put("签收时间", leescoreOrder.getVirtualSignTime());
            map.put("支付积分", leescoreOrder.getScoreTotal());
            map.put("支付货币", leescoreOrder.getMoneyTotal());
            map.put("回馈备注", leescoreOrder.getResultOther());
            map.put("实际支付积分", leescoreOrder.getTradeScore());
            map.put("实际付款", leescoreOrder.getTradeMoney());
            map.put("实际付款时间", leescoreOrder.getTradeTime());
            map.put("自动清理:0=清理,1=不清理", leescoreOrder.getAuthClearLevel());
            map.put("订单处理结果", leescoreOrder.getPayMsg());
            map.put(" weigh",  leescoreOrder.getWeigh());
            map.put(" updatetime",  leescoreOrder.getUpdatetime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}